from datetime import date, datetime
from decimal import Decimal
from enum import Enum
from typing import Optional, List

from pydantic import BaseModel, Field, field_validator, ConfigDict

from backend.models.member import CertificatesStatus


class Transaction_TypeEnum(str, Enum):
    """交易类型枚举"""
    RECHARGE = "recharge"
    CONSUMPTION = "consumption"
    REFUND = "refund"


# ============ 会员相关模型 ============

class MemberBase(BaseModel):
    """会员基础模型"""
    name: str = Field(..., min_length=1, max_length=100, description="会员姓名")
    phone_num: str = Field(..., description="联系方式")
    initial_balance: Decimal = Field(default=Decimal("0.00"), ge=0, description="初始余额")
    note: Optional[str] = Field(None, max_length=500, description="会员备注")


class MemberCreate(MemberBase):
    """创建会员模型"""
    pass


class MemberUpdate(BaseModel):
    """更新会员模型"""
    name: str = Field(None, min_length=1, max_length=100, description="会员姓名")
    phone_num: str = Field(..., description="联系方式")
    note: Optional[str] = Field(None, max_length=500, description="会员备注")


class MemberResponse(BaseModel):
    """会员响应模型"""
    id: int
    name: str
    phone: str
    registration_date: date
    current_balance: Decimal
    last_consumption_date: Optional[datetime]
    total_consumption: Decimal
    consumption_count: int
    created_at: datetime
    updated_at: datetime
    balance_status: str
    description: Optional[str]

    class Config:
        from_attributes = True


# ============ 交易相关模型 ============
class TransactionBase(BaseModel):
    """交易基础模型"""

    member_id: int = Field(..., gt=0, description="会员ID")
    transaction_type: Transaction_TypeEnum = Field(..., description="交易类型")
    amount: Decimal = Field(..., gt=0, description="交易金额")
    transaction_state: Optional[str] = Field('正常', max_length=200, description="交易描述")
    description: Optional[str] = Field(None, max_length=200, description="交易描述")


class TransactionCreate(TransactionBase):
    """创建交易模型"""
    transaction_id: int = Field(None, description="交易ID")
    pass


class TransactionResponse(BaseModel):
    """交易响应模型"""
    member_name: str
    member_id: int
    id: int
    amount: float
    transaction_date: datetime
    zh_cn_display: str
    amount_display: str
    transaction_state: str
    description: str

    class Config:
        from_attributes = True


# ============ 搜索相关模型 ============

class SearchConditions(BaseModel):
    """搜索条件模型"""
    name: Optional[str] = Field(None, max_length=100, description="会员姓名")
    phone: Optional[str] = Field(None, description="联系方式")
    member_code: Optional[str] = Field(None, max_length=20, description="会员编号")
    registration_date_start: Optional[date] = Field(None, description="登记开始日期")
    registration_date_end: Optional[date] = Field(None, description="登记结束日期")
    min_balance: Optional[Decimal] = Field(None, ge=0, description="最小余额")
    max_balance: Optional[Decimal] = Field(None, ge=0, description="最大余额")
    page: int = Field(default=1, ge=1, description="页码")
    page_size: int = Field(default=20, ge=1, le=100, description="每页数量")

    @field_validator('registration_date_end')
    def validate_date_range(cls, v, info):
        """验证日期范围
          v  registration_date_end
          info 是整个模型
        """
        if info is not None:
            values = info.data
            if v is not None and 'registration_date_start' in values:
                start_date = values['registration_date_start']
                if start_date is not None and v < start_date:
                    raise ValueError('结束日期不能早于开始日期')
            return v

    @field_validator('max_balance')
    def validate_balance_range(cls, v, info):
        """验证余额范围
        v  最大余额值
        """
        if info is not None:
            values = info.data
            if v is not None and 'min_balance' in values:
                min_balance = values['min_balance']
                if min_balance is not None and v < min_balance:
                    raise ValueError('最大余额不能小于最小余额')
            return v


class SearchResult(BaseModel):
    """搜索结果模型"""
    members: List[MemberResponse]
    total: int = Field(..., description="总数量")
    page: int = Field(..., description="当前页码")
    page_size: int = Field(..., description="每页数量")
    total_pages: int = Field(1, description="总页数")

    @field_validator('total_pages', mode='after', check_fields=False)
    def calculate_total_pages(cls, v, info):
        """计算总页数"""
        if info is not None:
            data = info.data  # info.data 相当于原来的 values
            total = data.get('total')  # 获取总数量
            page_size = data.get('page_size')  # 获取每页的数量
            if total is not None and page_size is not None:
                return (total + page_size - 1) // page_size  # 返回
            return v


# ============ 导出相关模型 ============

class ExportRequest(BaseModel):
    """导出请求模型"""
    conditions: Optional[SearchConditions] = Field(None, description="搜索条件")
    fields: List[str] = Field(default_factory=lambda: [
        "member_code", "name", "phone", "registration_date",
        "current_balance", "total_consumption", "consumption_count", 'last_consumption_date'
    ], description="导出字段")
    format: str = Field(default="excel", description="导出格式")

    @field_validator('fields')
    def validate_fields(cls, v):
        """验证要导出的字段"""
        allowed_fields = {
            "member_code", "name", "phone", "registration_date",
            "current_balance", "initial_balance", "total_consumption",
            "consumption_count", "last_consumption_date", "note",
            "created_at", "updated_at"
        }
        invalid_fields = set(v) - allowed_fields
        if invalid_fields:
            raise ValueError(f'无效的导出字段: {", ".join(invalid_fields)}')
        return v


# ============ 响应模型 ============
class MessageResponse(BaseModel):
    """消息响应模型"""
    message: str = Field(..., description="响应消息")
    success: bool = Field(default=True, description="是否成功")


class StatisticsResponse(BaseModel):
    """统计响应模型"""
    total_members: int = Field(..., description="总会员数")
    active_members: int = Field(..., description="活跃会员数")
    total_balance: Decimal = Field(..., description="总余额")
    total_consumption: Decimal = Field(..., description="总消费金额")
    today_registrations: int = Field(..., description="今日新增会员")
    today_consumption: Decimal = Field(..., description="今日消费金额")


# ============ 存单模型 ============


class MemberCertificateBase(BaseModel):
    """存单基础模型 创建存单"""
    member_id: Optional[int] = Field(..., description="用户ID")
    certificates: str = Field(..., description="存单内容")
    certificates_status: Optional[CertificatesStatus] = Field(default=CertificatesStatus.YES, description="存单状态")


class MemberCertificateChange(MemberCertificateBase):
    """改变存单状态的模型"""
    certificate_id: int = Field(..., description="存单ID")


class MemberCertificateResponse(BaseModel):
    """回复模型"""
    id: int
    member_id: int
    certificates: str
    certificates_status: str
    created_at: datetime

    class Config:
        from_attributes = True
